<template>
  <div>
    <p>1.直接获取 state 里的值 {{ todos }}</p>
    <p>2.通过 gettters 获取 state 里的值 {{ todos2 }}</p>
    <p>3.通过 mutations 触发一个方法，往todos里动态添加值</p>
    <section>
      <input type="text" v-model="todoMessage" />
      <button @click="addTodo">添加</button>
    </section>
    <p>4.通过 actions 异步触发一个方法，往todos里动态添加值（异步触发，等待 500ms）</p>
    <section>
      <input type="text" v-model="todoMessage2" />
      <button @click="addTodo2">添加</button>
    </section>
  </div>
</template>

<script>
// 第一步 从 vue 中引入这些辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
// import {  mapGetters, mapMutations, mapActions } from "vuex";
// import { createNamespacedHelpers } from 'vuex'
// const { mapState } = createNamespacedHelpers('vuexStateGetters')

export default {
  data() {
    return {
      todoMessage: 'todo...',
      todoMessage2: 'todo...'
    }
  },
  methods: {
    // 第三步 在 方法 中使用 mapMutations 和 mapActions（加上命名空间）
    ...mapMutations('vuexStateGetters', ['ADD_TODO']),
    ...mapActions('vuexStateGetters', ['ASYNC_ADD_TODO']),
    // 如果是不想通过 mapMutations 解构出来，也可以一个一个的也是可以的，和不区分模块化写法一样，只是这个要加上一个命名开空间而已，actions 的同理
    // this.$store.commit('/vuexStateGetters/ADD_TODO)

    addTodo() {
      let todo = {
        id: Math.random().toString().slice(2),
        text: this.todoMessage,
        done: true
      }
      // 需要通过 commit 发起调用 Vuex 里的 mutations 里的属性
      // this.$store.commit("ADD_TODO", todo);
      // this.commit("ADD_TODO", todo);
      this.ADD_TODO(todo) // 简写，直接使用从 mapMutations 中解构出来的
      // this.$store.dispatch('/vuexStateGetters/ASYNC_ADD_TODO)
      this.todoMessage = ''
    },
    addTodo2() {
      let todo = {
        id: Math.random().toString().slice(2),
        text: this.todoMessage2 + '异步触发的，需要等待 500ms',
        done: true
      }
      // 需要通过 commit 发起调用 Vuex 里的 mutations 里的属性
      // this.$store.dispatch("ASYNC_ADD_TODO", todo);
      // this.dispatch("ASYNC_ADD_TODO", todo);
      this.ASYNC_ADD_TODO(todo) // 简写，直接使用从 mapMutations 中解构出来的
      this.todoMessage2 = ''
    }
  },
  computed: {
    // 第二步 在 计算属性 中使用 mapState 和 mapGetters
    // ...mapState(["todos"]),
    // 如果传一个对象 还可以取别名
    // ...mapState({
    //   aaa:'todos'
    // }),
    //  AAA2、进行了模块化后的第二种写法（针对值比较多的情况，使用这种方式更方便）
    // 进行了模块化后 ，必须要使用了命名空间后，通过命名空间的名字获取
    // 方式一：第一个参数为命名空间名，第二个参数接收一个数组放需要的 state 值
    ...mapState('vuexStateGetters', ['todos']),
    ...mapGetters('vuexStateGetters', ['GET_MESSAGE', 'GET_TODOS']),
    // 方式二：基于 createNamespacedHelpers 单独创建基于某个命名空间的 mapState 辅助函数
    // ...mapState(['todos']),

    // 从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态
    message() {
      // return this.$store.state.message;
      // return this.message
    },
    message2() {
      // 注意：也是属性，不是方法，不用加括号执行
      // return this.$store.getters.GET_MESSAGE;
      // return this.GET_MESSAGE;
    },
    //  AAA1、进行了模块化后的第一种写法（针对单一值的，如果值比较多的话，推荐使用方式二）
    // 进行了模块化后 ，必须要使用了命名空间后，通过命名空间的名字获取，这是方式一
    // todos() {
    // return this.$store.state.vuexStateGetters.todos;
    // },
    todos2() {
      // 注意：也是属性，不是方法，不用加括号执行
      // return this.$store.getters.GET_TODOS;
      return this.GET_TODOS // 简写
    }
  }
}
</script>

<style lang="scss" scoped>
div {
  section {
    input {
      margin-right: 10px;
      border: solid 1px #ddd;
      padding: 6px;
      outline: none;
    }
    button {
      border: solid 1px #ddd;
      background: #d35400;
      color: #fff;
      padding: 6px 8px;
      margin: 4px;
      border-radius: 10px;
      cursor: pointer;
      &.danger {
        background: #f1c40f;
      }
      &:hover {
        background: #c0392b;
      }
    }
  }
}
</style>